﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.Xml.Linq;
using System.Web;
using System.IO;
using System.Configuration;

namespace TireService.Data
{
    public class Interfaces
    {
        /// <summary>
        /// Interface function that read xml files and creates customers and customersubscriptions
        /// </summary>
        /// <param name="PartnerId">Id on partner to activate interface for</param>
        public void GenerateCustomerAndSubscription(int PartnerId)
        {
            try
            {
                // Instatiate datalayer
                TireServiceDB db = new TireServiceDB();

                // Get partner
                PartnerListEDI partner = db.GetPartnerEDI(PartnerId);

                if (partner == null)
                {
                    // Error, partner not found
                    throw new ArgumentException("Partner not found");
                }

                if (partner.InActive)
                {
                    // Error, partner inactive
                    throw new ArgumentException("Partner is inactive");
                }

                // Load xml file
                XDocument interfaceXmlFile = new XDocument();
                interfaceXmlFile = XDocument.Load(HttpContext.Current.Server.MapPath("Interfaces\\Data\\" + partner.XMLInterfaceFileName));

                // Read XML file into object
                var customers = from p in interfaceXmlFile.Descendants("customer")
                                select new
                                {
                                    Name = p.Element("name").Value,
                                    Address = p.Element("address").Value,
                                    ZipCode = p.Element("zipcode").Value,
                                    City = p.Element("city").Value,
                                    Country = Convert.ToInt32(p.Element("country").Value),
                                    Phone = p.Element("phone").Value,
                                    Mobile = p.Element("mobile").Value,
                                    Email = p.Element("email").Value,
                                    Createdate = p.Element("createdate").Value,
                                    Quantity = p.Element("quantity").Value,
                                    SubscriptionId = p.Element("subscriptionid").Value,
                                    Price = p.Element("price").Value,
                                    Id = p.Element("orderid").Value
                                };

                if (PartnerId == 1)
                {
                    // HACK: Hardcode what subscription Benify is buying at Mobilhjulskift
                    string subscriptionid = "6";

                    // Partner is Benify - change customer source data (SubscriptionId is predefined to 6: BronzePlus Subscription, Yearly)
                    customers = from p in interfaceXmlFile.Descendants("customer")
                               select new
                               {
                                   Name = p.Element("name").Value,
                                   Address = p.Element("address").Value,
                                   ZipCode = p.Element("zipcode").Value,
                                   City = p.Element("city").Value,
                                   Country = Convert.ToInt32(p.Element("country").Value),
                                   Phone = p.Element("phone").Value,
                                   Mobile = p.Element("mobile").Value,
                                   Email = p.Element("email").Value,
                                   Createdate = p.Element("createdate").Value,
                                   Quantity = p.Element("quantity").Value,
                                   SubscriptionId = subscriptionid,
                                   Price = db.GetPartnerSubscriptionPrice(PartnerId, Convert.ToInt32(subscriptionid)).ToString(),
                                   Id = p.Element("benifyid").Value // HACK: Different xml scheme for Benify xml
                               };
                }                    

                // Read object
                foreach (var customer in customers)
                {
                    try
                    {
                        // Define system userid (Used for logging)
                        Guid SystemUserId = new Guid(ConfigurationSettings.AppSettings["SystemUserId"].ToString()); // System ID - Jannik79

                        // Check that customer order has not already been processed
                        if (db.ExternalOrderInterfaces.SingleOrDefault(p => p.ExternalOrderId == customer.Id & p.SubscriptionId == Convert.ToInt32(customer.SubscriptionId)) != null)
                        {
                            // Create customer
                            Customer newcustomer = new Customer();
                            string phone1 = "";
                            string phone2 = "";
                            int phone1type = 0;
                            int? phone2type = null;

                            if (customer.Mobile != null & customer.Phone != null)
                            {
                                phone1 = customer.Phone;
                                phone1type = 1;
                                phone2 = customer.Mobile;
                                phone2type = 0;
                            }
                            else
                            {
                                if (customer.Mobile != null & customer.Phone == null)
                                {
                                    phone1 = customer.Mobile;
                                    phone1type = 0;
                                    phone2 = null;
                                    phone2type = null;
                                }
                                else
                                {
                                    if (customer.Mobile == null & customer.Phone != null)
                                    {
                                        phone1 = customer.Phone;
                                        phone1type = 1;
                                        phone2 = null;
                                        phone2type = null;
                                    }
                                    else
                                    {
                                        // Error, missing data in customer order
                                        throw new ArgumentException("Oprettelse af kunde ikke mulig - data ikke valide. Kunde/OrdreId: " + customer.Id.ToString());
                                    }
                                }
                            }

                            CustomerBLL customerBLL = new CustomerBLL();
                            newcustomer = customerBLL.UpdateCustomer(db, newcustomer, 0, partner.ActAsParentCustomer, partner.CustomerId, partner.ParentPayInvoice, partner.IsCompany, null, null, customer.Name, customer.Address, customer.ZipCode, customer.City, customer.Country, customer.Address, customer.ZipCode, customer.City, phone1, phone1type, phone2, phone2type, customer.Email, true, partner.SyncToEconomic, partner.ManualInvoicing, partner.InvoicePBS, true);

                            // Initiate customer subscription business logic
                            CustomerSubscriptionBLL customersubscriptionBLL = new CustomerSubscriptionBLL();

                            // Get subscription 
                            Subscription subscription = db.GetSubscription(Convert.ToInt32(customer.SubscriptionId));

                            // Calculate subscription renew date
                            // Renewal dates: 01/03 and 01/09
                            DateTime LastRenewalDate = customersubscriptionBLL.CalculateLastRenewalDate(Convert.ToDateTime(DateTime.Now));
                            DateTime NextRenewalDate = customersubscriptionBLL.CalculateNextRenewalDate(LastRenewalDate, subscription);
                            decimal Price = Convert.ToDecimal(customer.Price); 
                            bool BalancingIncluded = subscription.BalancingIncluded;

                            // Create customersubscription
                            CustomerSubscription customersubscription = new CustomerSubscription();
                            customersubscriptionBLL.UpdateCustomerSubscription(db, customersubscription, newcustomer, 0, subscription.SubscriptionId, LastRenewalDate, NextRenewalDate, false, BalancingIncluded, Price, SystemUserId, true, "Bestilling af abonnement og bil");

                            // Mark in external interface table that customer has been processed
                            ExternalOrderInterface externalorder = new ExternalOrderInterface();
                            externalorder.PartnerId = PartnerId;
                            externalorder.ExternalOrderId = customer.Id;
                            externalorder.Quantity = Convert.ToInt32(customer.Quantity);
                            externalorder.SubscriptionId = Convert.ToInt32(customer.SubscriptionId);

                            newcustomer.ExternalOrderInterfaces.Add(externalorder);

                            db.ExternalOrderInterfaces.InsertOnSubmit(externalorder);

                            // Submit to database
                            db.SubmitChanges();

                            // TODO: 31-05-2013 - Below code can be made if customer can place ordre on more subscriptions that are also different
                            //// Check if more orders on same customer
                            //if (customers.Count(p => p.Id == customer.Id) > 1)
                            //{
                            //    // More ordres exists on customer - add one more interface record
                            //    var customer2 = customers.SingleOrDefault(p => p.Id == customer.Id
                            //}

                            // Sync customer with E-conomic
                            EconomicInterface ecoInterface = new EconomicInterface();

                            // Create debtor in E-conomic
                            ecoInterface.CreateDebtor(newcustomer, db);

                            // Send email to customer with finalise signup link
                            EmailNotificationServices emailService = new EmailNotificationServices();
                            emailService.Interface_FinaliseSignUp_SendCustomerEmail(newcustomer.Email, newcustomer.Name, newcustomer.CustomerId);
                        }
                    }
                    catch (Exception ex)
                    {
                        // TODO: Create log on exception
                    }
                }

                // Dispose database connection
                db.Dispose();
            }
            catch (Exception ex)
            {
                
            }
            
        }

        public bool CopyOrderXMLfileFromBenify(Uri serverUri, string BenifyUserName, string BenifyPassword)
        {
            // The serverUri parameter should start with the ftp:// scheme. 
            if (serverUri.Scheme != Uri.UriSchemeFtp)
            {
                return false;
            }

            // Get the object used to communicate with the server.
            WebClient request = new WebClient();

            // Login to FTP
            request.Credentials = new NetworkCredential(BenifyUserName, BenifyPassword);
            try
            {
                // Download file from FTP
                byte[] newFileData = request.DownloadData(serverUri.ToString());
                string fileString = System.Text.Encoding.UTF8.GetString(newFileData);
                //Debug.WriteLine(fileString);

                // Save file to other location
                string folder = Path.Combine(HttpContext.Current.Request.PhysicalApplicationPath, "Interfaces\\Data\\Benify.xml");
                using (FileStream fs = File.Create(folder, 1024))
                {
                    Byte[] info = new UTF8Encoding(true).GetBytes(fileString);
                    // Add some information to the file.
                    fs.Write(info, 0, info.Length);
                }
            }
            catch (WebException e)
            {
                Debug.WriteLine(e.ToString());
            }
            return true;

        }

    }
}
